package com.demo.sso.interceptor;

import com.demo.sso.reids.RedisManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;

/**
 * 请添加模块注释
 *
 * @author fengjy
 * @date 2018-10-29 0:07
 */

@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

//    private static Logger logger = LoggerFactory.getLogger(LoginInterceptor.class);

    @Autowired
    private RedisManager redisManager;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        try {
            log.info("------------ 在访问controller之前的处理逻辑 start ------------");

//            校验用户是否已经登录,如果登录过,将之前用户踢掉,同时更新缓存中用户信息
            Subject subject = SecurityUtils.getSubject();
            Serializable token = subject.getSession().getId();
            if (token == null) {
                //重定向到login.html
                redirect(request, response);
                return false;
            }
            //获取用户id
            Object userIdObj = redisManager.get("sys:login:user_token_"+token.toString());
            if(null != userIdObj) {
                String userId = userIdObj.toString();
                String tokenPre = redisManager.get("sys:user:id_"+userId).toString();
                if(!token.equals(tokenPre)) {
                    //重定向到login.html
                    redirect(request, response);
                    return false;
                }else {
                    Long expire = redisManager.ttl("sys:login:user_token_"+token.toString());
                    //过期时间小于1分钟的,更新token
                    if(expire < 1 * 60 * 1000) {
                        redisManager.expire("sys:login:user_token_"+token.toString(), 60*30);
                    }
                }
            }else {
                redirect(request, response);
                return false;
            }


//            Subject currentUser = SecurityUtils.getSubject();
//            Serializable sessionId = currentUser.getSession().getId();
//            Session session = ShiroSessionRedisUtil.getSession(sessionId);
//            if (null == session) {
//                response.sendRedirect(request.getContextPath() + Const.LOGIN);
//            }
//            LoginUser user = (LoginUser) session.getAttribute(Const.SESSION_USER);
//            if (user != null) {
//
//                /*校验token，单点登录*/
//                Cookie[] cookies = request.getCookies();
//                boolean hasTokenCookie = false;
//                for (Cookie cookie : cookies) {
//                    if (ShiroSessionRedisConstant.SSOTOKEN_COOKIE_KEY.equals(cookie.getName())) {
//                        hasTokenCookie = true;
//                        String tokenRedis = RedisUtil.getString(ShiroSessionRedisConstant.SHIROSESSION_REDIS_DB, ShiroSessionRedisConstant.SSOTOKEN_REDIS_PREFIX + user.getUserName(), ShiroSessionRedisConstant.SHIROSESSION_REDIS_EXTIRETIME);
//                        if (StringUtils.isBlank(tokenRedis) || !tokenRedis.equalsIgnoreCase(cookie.getValue())) {
//                            response.sendRedirect(request.getContextPath() + Const.LOGIN);
//                        }
//                    }
//                }
//                if (!hasTokenCookie) {
//                    response.sendRedirect(request.getContextPath() + Const.LOGIN);
//                }
//
//
//                path = path.substring(1, path.length());
//                boolean b = Jurisdiction.hasJurisdiction(path);
//                if (!b) {
//                  response.sendRedirect(request.getContextPath() + Const.LOGIN);
//                }
//                return b;
//            } else {
//                //登陆过滤
//                response.sendRedirect(request.getContextPath() + Const.LOGIN);
//                return false;
//                //return true;
//            }



            log.info("------------ 在访问controller之前的处理逻辑 end ------------");
        } catch (Exception e) {
            log.error("preHandle = {}", e);
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
    }


    //对于请求是ajax请求重定向问题的处理方法
    public void redirect(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //获取当前请求的路径
        String basePath = request.getScheme() + "://" + request.getServerName() + ":"  + request.getServerPort()+request.getContextPath();
//        response.getOutputStream().write("账号在别处登录。".getBytes("UTF-8"));
        //如果request.getHeader("X-Requested-With") 返回的是"XMLHttpRequest"说明就是ajax请求，需要特殊处理 否则直接重定向就可以了
        if("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))){
            //告诉ajax我是重定向
            response.setHeader("REDIRECT", "REDIRECT");
            //告诉ajax我重定向的路径
            response.setHeader("CONTENTPATH", basePath+ "/templates/login.html");
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        }else{
            response.sendRedirect(basePath + "/templates/login.html");
        }
    }

}
